package com.frank.oj.service.oj.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.IdUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.frank.model.entity.problem.Language;
import com.frank.model.entity.problem.Problem;
import com.frank.model.entity.problem.ProblemTag;
import com.frank.model.entity.problem.Tag;
import com.frank.oj.common.result.CommonResult;
import com.frank.oj.manager.CommonManager;
import com.frank.oj.model.vo.CaptchaVO;
import com.frank.oj.model.vo.ProblemTagVO;
import com.frank.oj.service.entity.common.TagEntityService;
import com.frank.oj.service.entity.problem.LanguageEntityService;
import com.frank.oj.service.entity.problem.ProblemEntityService;
import com.frank.oj.service.entity.problem.ProblemLanguageEntityService;
import com.frank.oj.service.entity.problem.ProblemTagEntityService;
import com.frank.oj.service.oj.CommonService;
import com.frank.oj.utils.RedisUtils;
import com.wf.captcha.ArithmeticCaptcha;
import com.wf.captcha.base.Captcha;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author frank
 * @Date 2024/3/22
 */
@Service
public class CommonServiceImpl implements CommonService {
    @Resource
    private CommonManager commonManager;
    @Resource
    private TagEntityService tagEntityService;
    @Resource
    private ProblemLanguageEntityService problemLanguageEntityService;
    @Resource
    private ProblemEntityService problemEntityService;
    @Resource
    private ProblemTagEntityService problemTagEntityService;
    @Resource
    private LanguageEntityService languageEntityService;
    @Resource
    private RedisUtils redisUtils;

    @Override
    public CommonResult<List<ProblemTagVO>> getProblemTagsAndClassification(String oj) {
        return CommonResult.successResponse(commonManager.getProblemTagsAndClassification(oj));
    }

    @Override
    public List<Tag> getAllProblemTags(String oj) {

        oj = oj.toUpperCase();
        LambdaQueryWrapper<Tag> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.isNull(Tag::getGid);
        if (!"ALL".equals(oj)) {
            queryWrapper.eq(Tag::getOj, oj);
        }
        return tagEntityService.list(queryWrapper);
    }

    @Override
    public List<Language> getLanguages(Long pid, Boolean all) {
        String oj = "ME";

        if (pid != null) {
            Problem problem = problemEntityService.getById(pid);
            if (problem.getIsRemote()) {
                oj = problem.getProblemId().split("-")[0];
            }
        }
        if ("GYM".equals(oj)) {
            oj = "CF";
        }

        LambdaQueryWrapper<Language> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(!StringUtils.isEmpty(all) && !all, Language::getOj, oj);
        List<Language> languageList = languageEntityService.list(queryWrapper);
        return languageList.stream()
                .sorted(Comparator.comparing(Language::getSeq, Comparator.reverseOrder())
                        .thenComparing(Language::getId))
                .collect(Collectors.toList());
    }

    @Override
    public Collection<Tag> getProblemTags(Long pid) {
        HashMap<String, Object> map = new HashMap<>();
        map.put("pid", pid);
        List<Long> tidList = problemTagEntityService.listByMap(map).stream().map(ProblemTag::getTid).collect(Collectors.toList());

        if (CollectionUtils.isEmpty(tidList)) {
            return new ArrayList<>();
        }
        return tagEntityService.listByIds(tidList);
    }

    @Override
    public CommonResult<CaptchaVO> getCaptcha() {
        //创建并初始化算术验证码对象。
        ArithmeticCaptcha captcha = new ArithmeticCaptcha(90, 30, 4);
        // 设置验证码的字符类型为默认类型
        captcha.setCharType(Captcha.TYPE_DEFAULT);
        // 设置算术表达式的长度为2（即两个数字相加或相减）
        captcha.setLen(2);

        String verCode = captcha.text().toLowerCase();
        String key = IdUtil.simpleUUID();

        redisUtils.set(key, verCode, 60); // 1分钟过期

        CaptchaVO captchaVO = new CaptchaVO();
        captchaVO.setImg(captcha.toBase64());
        captchaVO.setCaptchaKey(key);

        return CommonResult.successResponse(captchaVO);
    }
}
